#include <lcir/Dag2Dag/Pattern.h>
#include <lcir/Utils/Result.h>

#include <iostream>
#include <queue>

#include "lcir/IR/IRRewritter.h"
namespace lcir {
Result PatternNode::match(Expression *expr) const {
  if (!expr) return failure();
  if (expr->getOpInstance() == opInstance) return success();
  return failure();
}
Result Pattern::match(Expression *rootExpr) const {
  // 这里我们用一个bfs依次比较
  // 这里把匹配出来的目标形状拿出来
  std::queue<PatternNode> q;
  std::queue<Expression *> exprq;
  q.push(root);
  exprq.push(rootExpr);
  while (!q.empty()) {
    auto node = q.front();
    auto *expr = exprq.front();
     q.pop();
    exprq.pop();
    if (failed(node.match(expr)) || node.getInputs().size() > expr->getOperands().size()) {
      return failure();
    }
    for (size_t i = 0; i < node.getInputs().size(); ++i) {
      q.push(node.getInputs()[i]);
      if (!expr->getOperand(i)->getValue()->getDefExpr()) return failure();
      auto *opExpr = expr->getOperand(i)->getValue()->getDefExpr();
      exprq.push(opExpr);
    }
  }
  return success();
}

Result Pattern::matchAndRewrite(Expression *root) const {
  auto res = match(root);
  if (failed(res)) return failure();
  IRRewritter b(root);
  return rewrite(root, b);
}
}  // namespace lcir